package org.example.database.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.example.database.DTO.ResumeDTO;
import org.example.database.Mapper.AdviceMapper;
import org.example.database.service.OllamaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
@Slf4j

public class OllamaServiceImpl implements OllamaService {

    private static final String OLLAMA_API_URL = "http://localhost:11434/api/generate";
    private final RestTemplate restTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private AdviceMapper adviceMapper;

    public OllamaServiceImpl() {
        this.restTemplate = new RestTemplate();
    }

    /**
     * 从简历文本中提取结构化信息
     */
    @Override
    public ResumeDTO extractResumeInfo(String resumeText) {
        log.info("开始解析简历文本...");

        String prompt = String.format(""" 
            你是一个只返回 JSON 的工具。请确保输出是一个合法的 JSON 对象，对象中的数据不需要使用数组进行存储，中间没有任何多余的自然语言或注释说明。
            
            字段如下（如果无内容请用 null，简历评估结果先生成后插入,不为null）：
            - name（姓名）
            - major（专业）
            - educationBackground（学历背景）
            - academy（毕业院校）
            - workExperience（工作/实习经历）
            - skill（技能，数组）
            - jobIntention（求职意向）
            - certificate（证书，数组）
            - timeOfGraduation（毕业时间）
            - timeOfEnrollment（入学时间）
            - assessmentResult（简历评估结果）

            简历文本：
            %s

            仅返回 JSON 对象，请严格遵守格式：
            {
              "name": ...,
              ...
            }
            """, resumeText);

        Map<String, Object> request = new HashMap<>();
        request.put("model", "qwen3:8b");
        request.put("prompt", prompt);
        request.put("stream", false);

        Map<String, Object> response = restTemplate.postForObject(OLLAMA_API_URL, request, Map.class);
        String rawResponse = (String) response.get("response");
        log.info("模型原始响应内容：{}", rawResponse);

        try {
            String jsonText = extractJsonBlock(rawResponse);
            log.info("提取的 JSON 内容为：{}", jsonText);
            return objectMapper.readValue(jsonText, ResumeDTO.class);
        } catch (Exception e) {
            log.error("解析AI模型响应失败，原始内容为：{}", rawResponse, e);
            throw new RuntimeException("解析AI模型响应失败", e);
        }
    }

    /**
     * 从文本中提取第一个 JSON 块
     */
    private String extractJsonBlock(String text) {
        Pattern pattern = Pattern.compile("\\{(?:[^{}]|\\{[^{}]*\\})*\\}", Pattern.DOTALL);
        Matcher matcher = pattern.matcher(text);
        if (matcher.find()) {
            return matcher.group();
        }
        throw new RuntimeException("未能从模型响应中提取出 JSON 内容");
    }

    /**
     * 匹配度计算
     */
    @Override
    public double calculateJobMatchScore(ResumeDTO resumeData, Map<String, Object> jobData) {
        String prompt = String.format("""
            请计算以下简历和职位之间的匹配度（0-1）。
            考虑因素包括：技能、教育背景、经验、职位要求等。

            简历数据：
            %s

            职位数据：
            %s

            仅返回0到1之间的匹配度分数。
            """, resumeData.toString(), jobData.toString());

        Map<String, Object> request = new HashMap<>();
        request.put("model", "qwen-8b");
        request.put("prompt", prompt);
        request.put("stream", false);

        Map<String, Object> response = restTemplate.postForObject(OLLAMA_API_URL, request, Map.class);
        String generatedText = (String) response.get("response");

        try {
            return Double.parseDouble(generatedText.trim());
        } catch (Exception e) {
            throw new RuntimeException("解析AI模型响应失败", e);
        }
    }

}
